{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 输入数据编码\n",
    "\n",
    "作者: [赵振宇](https://github.com/15947470421)\n",
    "\n",
    "感谢朱文凯为本教程提供的建议"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在人工神经网络（ANN）中，数据都是“模拟”的，是一个具体的数值。\n",
    "\n",
    "对于脉冲神经网络（SNN），数据都是“数字”的，脉冲信号数据仅有2种状态：脉冲（为1），无脉冲（为0）。\n",
    "\n",
    "所以，就让我们从如何将输入的数据编码为脉冲信号数据开始我们的学习吧。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一个最简单的脉冲数据编码方式就是设定一个阈值，当原始数据大于该阈值则编码为脉冲（1），否则不产生脉冲（0）。但是，这种方法的缺点很明显：原始数据的大小信息几乎全部丢失了。\n",
    "\n",
    "为了保存原始数据的大小信息，一种可能的方法就是将原始信息的大小转化为产生脉冲的概率：如果原始数据比较大，那么就意味着该数据被编码为脉冲的概率较大，反之则概率较小。\n",
    "\n",
    "如果我们只进行一次编码，我们其实并不能反映出来数据的概率。在实际情况中，我们会设定一个仿真周期`T`，独立重复的进行`T`次编码，才可以在仿真周期`T`中反映出概率。\n",
    "\n",
    "惊蛰框架中的`spikingjelly.activation_based.encoding`中包含了编码的相关函数，这里我们使用*泊松编码器*进行讲解，读者也可以自行选择其他编码器。\n",
    "\n",
    "泊松编码器的编码原理是：将输入的数据，映射到概率P，最终以概率P产生脉冲（1）。\n",
    "\n",
    "在仿真周期T中，该数据产生脉冲的概率为P。回想概率论中的内容，该过程与泊松分布相同，这也是泊松编码器名字的由来。\n",
    "\n",
    "以一个灰度图像数据为例，比如某个像素点的数据为100，由于灰度图像的像素值在[0, 255]，归一化后$100/255=0.39$，所以最终的概率P为0.39，那么该像素点有39%(0.39)的概率产生脉冲。\n",
    "\n",
    "使用泊松编码之后的效果为：原始图像中数值较高的像素点，在仿真周期T中，产生脉冲的概率较高；而数值较低的像素点，产生脉冲的概率较低。\n",
    "\n",
    "*注意：必须保证输入的数据处于[0 - 1]之间*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = tensor([0.7226])\n",
      "x_encoded = tensor([0., 1., 1., 1., 1., 1., 1., 1., 1., 1.])\n",
      "rate =  0.9000\n"
     ]
    }
   ],
   "source": [
    "# import\n",
    "import torch\n",
    "\n",
    "from spikingjelly.activation_based import encoding\n",
    "\n",
    "# 仿真周期\n",
    "T = 10\n",
    "\n",
    "# 随机生成一个处于[0-1]之间的数据x\n",
    "x = torch.rand(1)\n",
    "print(f\"x = {x}\")\n",
    "\n",
    "# 配置编码器\n",
    "encoder = encoding.PoissonEncoder()\n",
    "x_encoded = torch.zeros(T)\n",
    "# 重复进行T次编码\n",
    "for t in range(T):\n",
    "    x_encoded[t] = encoder(x)\n",
    "print(f\"x_encoded = {x_encoded}\")\n",
    "\n",
    "num = x_encoded.sum() # 将编码后的1相加\n",
    "rate = num / T # 得到编码后的概率\n",
    "print(f\"rate = {rate: .4f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最终编码后的数据向量`x_encoded`中脉冲（1）的概率`rate`，和我们随机生成的原始数据`x`接近（如果相差较大，请多运行几次并观察结果），这就是代表：将x编码到时间周期T=10中。换句话说，在10个单位时间中出现脉冲（1）的概率为x。\n",
    "\n",
    "让我们将仿真周期T增加为100."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = tensor([0.9290])\n",
      "x_encoded = tensor([1., 1., 1., 1., 0., 1., 1., 1., 1., 1., 0., 1., 1., 1., 1., 1., 1., 1.,\n",
      "        1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 0., 1., 1.,\n",
      "        1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n",
      "        1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n",
      "        1., 1., 1., 1., 1., 0., 1., 1., 1., 1., 0., 1., 1., 1., 1., 1., 1., 1.,\n",
      "        0., 1., 1., 1., 1., 1., 1., 1., 1., 1.])\n",
      "rate =  0.9400\n"
     ]
    }
   ],
   "source": [
    "# 仿真周期\n",
    "T = 100 # 把仿真时间T增加到100\n",
    "\n",
    "# 随机生成一个处于[0-1]之间的数据x\n",
    "x = torch.rand(1)\n",
    "print(f\"x = {x}\")\n",
    "\n",
    "# 配置编码器\n",
    "encoder = encoding.PoissonEncoder()\n",
    "x_encoded = torch.zeros(T)  # 编码后的数据\n",
    "for t in range(T):\n",
    "    x_encoded[t] = encoder(x)\n",
    "print(f\"x_encoded = {x_encoded}\")\n",
    "\n",
    "num = x_encoded.sum() # 将编码后的1相加\n",
    "rate = num / T # 得到编码后的概率\n",
    "print(f\"rate = {rate: .4f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到，当我们将T从10增加到100，最终的概率与输入的x更接近。理论上，仿真周期T越大，输出的脉冲频率越接近实际输入值。当$T \\rightarrow +\\infty$，输出的脉冲频率越等于实际输入值。\n",
    "\n",
    "但是，在实际的SNN中，我们通常并不会将T设置的非常大，因为最终的训练效果与T的大小并无直接关系，我们通常设置T为[10, 50]即可。\n",
    "\n",
    "上面的例子只是一个简单的演示.接下来，让我们将输入的数据从单个数字推广到向量类型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = tensor([0.4407, 0.2672, 0.5331, 0.7221, 0.4975, 0.5007, 0.5003, 0.0760, 0.8638,\n",
      "        0.4385])\n",
      "x_encoded = tensor([[1., 1., 0., 1., 0., 1., 1., 0., 1., 0.],\n",
      "        [0., 0., 0., 1., 1., 0., 1., 0., 1., 0.],\n",
      "        [1., 1., 1., 1., 0., 0., 0., 0., 1., 0.],\n",
      "        [1., 1., 1., 1., 0., 1., 0., 0., 0., 1.],\n",
      "        [0., 1., 1., 1., 0., 0., 1., 0., 1., 0.],\n",
      "        [0., 1., 1., 1., 1., 0., 0., 0., 1., 1.],\n",
      "        [1., 0., 0., 1., 0., 1., 0., 1., 0., 1.],\n",
      "        [1., 1., 1., 1., 1., 0., 0., 0., 1., 1.],\n",
      "        [0., 1., 1., 1., 0., 0., 0., 0., 1., 1.],\n",
      "        [1., 0., 1., 1., 0., 1., 1., 0., 1., 1.],\n",
      "        [1., 0., 1., 1., 0., 1., 0., 0., 1., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 1., 0., 1., 0.],\n",
      "        [1., 0., 1., 1., 1., 1., 0., 0., 1., 1.],\n",
      "        [0., 0., 0., 1., 0., 0., 1., 0., 1., 1.],\n",
      "        [0., 0., 1., 1., 1., 1., 1., 0., 0., 1.],\n",
      "        [0., 0., 0., 0., 1., 0., 0., 0., 1., 1.],\n",
      "        [1., 0., 1., 1., 0., 1., 0., 0., 1., 0.],\n",
      "        [0., 0., 0., 1., 0., 1., 0., 1., 1., 1.],\n",
      "        [1., 0., 0., 0., 0., 1., 0., 0., 1., 1.],\n",
      "        [1., 1., 0., 0., 0., 1., 1., 0., 1., 1.]])\n",
      "rate = tensor([0.5500, 0.4000, 0.5500, 0.8000, 0.3000, 0.5500, 0.4000, 0.1000, 0.8500,\n",
      "        0.6500])\n"
     ]
    }
   ],
   "source": [
    "# 仿真周期\n",
    "T = 20 # 把仿真时间T设置为20\n",
    "size = 10 # 生成的数据大小为10\n",
    "\n",
    "# 随机生成一个大小为[size]的数据x\n",
    "x = torch.rand([size])\n",
    "print(f\"x = {x}\")\n",
    "\n",
    "# 配置编码器\n",
    "encoder = encoding.PoissonEncoder()\n",
    "x_encoded_size = [T, size] # 编码后的数据大小\n",
    "x_encoded = torch.zeros(x_encoded_size) # 编码后的数据\n",
    "# 开始按照时间逐步编码\n",
    "for t in range(T):\n",
    "    x_encoded[t] = encoder(x)\n",
    "print(f\"x_encoded = {x_encoded}\")\n",
    "\n",
    "num = x_encoded.sum(dim=0) # 将编码后的脉冲(1)按照维度0（时间维度）求和\n",
    "rate = num / T # 得到编码后的概率\n",
    "print(f\"rate = {rate}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "编码之后的输出是一个大小为[T, size]的矩阵，矩阵的每一行表示一个时刻,每一列表示单个数据编码后的结果。\n",
    "\n",
    "趁热打铁，让我们将数据拓展为矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = tensor([[0.1395, 0.6151, 0.0451, 0.3333, 0.1260],\n",
      "        [0.1068, 0.9455, 0.4497, 0.4482, 0.4981],\n",
      "        [0.7679, 0.1980, 0.8419, 0.6455, 0.8471],\n",
      "        [0.5639, 0.2257, 0.2223, 0.8061, 0.9546],\n",
      "        [0.2504, 0.4019, 0.5377, 0.1807, 0.2393]])\n",
      "rate = tensor([[0.1000, 0.5000, 0.0500, 0.2500, 0.3000],\n",
      "        [0.2500, 0.9500, 0.5500, 0.5000, 0.4500],\n",
      "        [0.9500, 0.4500, 0.8000, 0.6500, 0.8500],\n",
      "        [0.5000, 0.2500, 0.3000, 0.8000, 1.0000],\n",
      "        [0.2500, 0.4500, 0.6000, 0.2500, 0.3000]])\n"
     ]
    }
   ],
   "source": [
    "T = 20 # 把仿真时间T设置为20\n",
    "size = [5, 5] # 输入数据大小\n",
    "\n",
    "# 随机生成一个大小为[size]的数据x\n",
    "x = torch.rand(size)\n",
    "print(f\"x = {x}\")\n",
    "\n",
    "# 配置编码器\n",
    "encoder = encoding.PoissonEncoder()\n",
    "x_encoded_size = [T, size[0], size[1]] # 编码后的数据大小\n",
    "x_encoded = torch.zeros(x_encoded_size) # 编码后的数据\n",
    "# 开始按照时间逐步编码\n",
    "for t in range(T):\n",
    "    x_encoded[t] = encoder(x)\n",
    "\n",
    "num = x_encoded.sum(dim=0) # 将编码后的脉冲(1)按照维度0（时间维度）求和\n",
    "rate = num / T # 得到编码后的概率\n",
    "print(f\"rate = {rate}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后，让我们将一个真实的MNIST数据集中的数据进行泊松编码，并查看效果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import\n",
    "import torch.utils.data as data\n",
    "import torchvision\n",
    "\n",
    "from matplotlib import pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "若报错`无法找到matplotlib`\n",
    "\n",
    "请尝试在anaconda中重新安装`matplotlib`库"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入数据集\n",
    "dataset_dir = \"./dataset\"\n",
    "# 加载训练数据集\n",
    "train_dataset = torchvision.datasets.MNIST(\n",
    "    root=dataset_dir,\n",
    "    train=True,\n",
    "    transform=torchvision.transforms.ToTensor(),\n",
    "    download=True\n",
    ")\n",
    "# 加载测试数据集\n",
    "test_dataset = torchvision.datasets.MNIST(\n",
    "    root=dataset_dir,\n",
    "    train=False,\n",
    "    transform=torchvision.transforms.ToTensor(),\n",
    "    download=True\n",
    ")\n",
    "\n",
    "# 使用DataLoader加载训练数据\n",
    "train_data_loader = data.DataLoader(\n",
    "    dataset=train_dataset,\n",
    "    batch_size=64,\n",
    "    shuffle=True,\n",
    "    drop_last=True,\n",
    "    pin_memory=True\n",
    ")\n",
    "# 使用DataLoader加载测试数据\n",
    "test_data_loader = data.DataLoader(\n",
    "    dataset=test_dataset,\n",
    "    batch_size=64,\n",
    "    shuffle=False,\n",
    "    drop_last=False,\n",
    "    pin_memory=True\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原始图像\n",
      "label: 7\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "编码后输出图像\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABj0AAALvCAYAAAA+vgenAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABpPUlEQVR4nO3df5zVdZ3o8ffg4DjiMInKDJOIZLqWmNzURFPBboK0kkpulreCbbUydFfN7aH52BXbXdFcudSaVm6ZblpWa+pVlGgFzEV21SubS2W6YlCArKZAiqPo5/7hZXJkgJnhnPn+ej4fj/NY55wz57znDOe158y7c05DSikFAAAAAABAwQ3KegAAAAAAAIBasPQAAAAAAABKwdIDAAAAAAAoBUsPAAAAAACgFCw9AAAAAACAUrD0AAAAAAAASsHSAwAAAAAAKAVLDwAAAAAAoBQsPQAAAAAAgFKw9KiYxYsXx8yZM+P555/f4rQJEybEhAkTBnymHTF37tyYOXNm1mPE//2//zfe//73x2677RZvectbYurUqfHkk09mPRbwJhpYe/fff3+cccYZceihh0ZTU1M0NDTEU089lelMQM80sLZeffXVmD17dpxwwgmx9957x6677hrveMc74sILL+zxNgaypYG195WvfCXGjRsXe+65ZzQ1NcU+++wTH/nIR2LZsmWZzgV0p3/1lVKKY489NhoaGuLss8/Oehz+P0uPilm8eHFceumlPYbummuuiWuuuWbgh9oBc+fOjUsvvTTTGX75y1/GhAkT4uWXX47vf//78a1vfSt+9atfxTHHHBP//d//nelsQHcaWHv/8i//Ej/5yU9in332iaOOOirTWYBt08Da2rhxY8ycOTNGjRoVc+bMiblz58aZZ54Z3/jGN+K9731vbNy4MbPZgC1pYO09++yzMXny5PjHf/zH+PGPfxyXXnppPPLII3HEEUfEY489lulswB/oX3199atfjSeeeCLrMXiTxqwHID/e+c53Zj1CIf31X/91NDU1xZ133hlDhw6NiIhDDz009t9///j7v//7uOKKKzKeEOgNDeyfv/qrv4pLLrkkIiL+/u//PhYuXJjtQEC/aGDfNTc3x/Lly2OPPfboOm7ChAmxzz77xJ/8yZ/EP//zP8fHPvaxDCcEeksD++fNf3QcP358jBs3Lt75znfGTTfdFF/84hczmgzoLf3bMU899VRcdNFFceONN8bUqVOzHoc38EqPCpk5c2b85V/+ZUREjB49OhoaGqKhoaHrD1RvfknbU089FQ0NDXHllVfGFVdcEfvuu280NzfHhAkT4le/+lW88sorceGFF0ZHR0e0trbGKaecEmvXrt3iem+55ZY48sgjY8iQIbHbbrvFpEmT4pFHHtnuvC+++GJccMEFMXr06Nhll11i2LBhcdhhh8V3v/vdiIiYPn16fPWrX42I6PpZ3vi2KimluOaaa2Ls2LHR3Nwcu+++e5x66qlbvO3UhAkTYsyYMfHTn/40xo0bF83NzfHWt741/uqv/ipeffXVbc64adOmuPPOO+NDH/pQ18IjImLUqFFx3HHHxY9+9KPt/pzAwNDA2jcwImLQIA8loAg0sPYN3GmnnbotPDZ7z3veExERK1eu3O7PCQwMDazP48Ce7LXXXhER0djof2MLeaB/9e3fpz71qTj++OPjlFNO6fX3MEASlbFy5cp0zjnnpIhIt956a3rggQfSAw88kNatW5dSSmn8+PFp/PjxXedfvnx5iog0atSoNGXKlHTnnXem73znO6mtrS0dcMAB6eMf/3j65Cc/me6+++70ta99Le22225pypQp3a7z7/7u71JDQ0P65Cc/me6888506623piOPPDINGTIkLVu2bJvzfvrTn0677rprmj17dlqwYEG688470+WXX57+4R/+IaWU0hNPPJFOPfXUFBFdP8sDDzyQXnrppZRSSmeeeWYaPHhw+tznPpfuueeedPPNN6cDDzwwtbW1pTVr1nRdz/jx49Mee+yROjo60le+8pU0b9689Od//ucpItKMGTO2OeMvf/nLFBHpq1/96hanXXDBBamhoSFt3Lhxm5cBDAwNrH0D3+zKK69MEZGWL1/ep+8D6k8D69/Aza6//voUEen222/v1/cDtaeB9W3gpk2b0ksvvZR+8YtfpJNOOikNHz48rVixotffD9SP/tWvf9ddd11qbW1Nv/3tb1NKaYceP1J7lh4Vs60/SG0tdIccckh69dVXu46fM2dOioj0wQ9+sNv3n3vuuSkiusK5YsWK1NjYmM4555xu59uwYUNqb29PH/7wh7c565gxY9LJJ5+8zfPMmDEj9bS7e+CBB1JEpKuuuqrb8StXrkzNzc3p85//fLefu6cnpmeeeWYaNGhQ+vWvf73V6//Xf/3XFBHpu9/97hanXXbZZSki0qpVq7b5MwADRwNr28A3s/SAfNPA+jYwpZR+85vfpLa2tnTYYYd1u92A7Glg/RrY1NSUIiJFRDrggAPSz3/+8159HzAw9K/2/fvNb36TWltb09e//vWu4yw98sV7UrBdH/jAB7q9fck73vGOiIj44z/+427n23z8ihUrIiJi3rx5sWnTpvjEJz4RmzZt6jrssssuMX78+O2+7/t73vOeuPvuu+PCCy+MhQsX9unDIO+8885oaGiIj33sY92uu729PQ455JAtrrulpSU++MEPdjvu9NNPj9deey3uu+++7V5fQ0NDv04D8k8Dt99AoLw0sPcN/N3vfhcf+MAHIqUUt9xyi7f/gxLQwN41cPHixfHAAw/Ed77znWhpaYnjjjsuli1b1uuZgfzRv2337zOf+UwccsghceaZZ/Z6PgaWN1lku4YNG9bt65133nmbx7/00ksREfH0009HRMThhx/e4+Vu74ngV77yldh7773jlltuiSuuuCJ22WWXmDRpUlx55ZWx//77b/N7n3766UgpRVtbW4+nv+1tb+v2dU/na29vj4iIZ599dqvXs/l9nHs6z+9+97toaGiIt7zlLducFcg3Ddx6A4Hy08DeNfC5556L448/Pn7729/Gvffeu8V1AMWkgb1r4Lvf/e6IiBg3blx88IMfjLe//e3xhS98IW6//fZefT+QP/q39f798Ic/jHvuuSfuv//+WLduXbfTXn755Xj++edjyJAhMXjw4G3OS31ZelA3e+65Z0S8HoNRo0b1+fuHDBkSl156aVx66aXx9NNPd216p0yZEr/85S+3e90NDQ3x05/+NJqamrY4/c3HbY7yG61ZsyYioscPqNxsv/32i+bm5nj00Ue3OO3RRx+Nt7/97bHLLrtsc1agnKrQQICtqVIDn3vuuXj/+98fy5cvj3/5l3+Jd73rXdv9HqDcqtTAN2tpaYkDDzwwfvWrX/X5e4Hiq0L//vM//zM2bdoU48aN2+K06667Lq677rr40Y9+FCeffPI256W+LD0qZvMdvC8vD+uvSZMmRWNjY/zXf/1XfOhDH9qhy2pra4vp06fHf/zHf8ScOXPixRdfjF133bXbz9Pc3Nx1/hNPPDEuv/zy+O1vfxsf/vCHt3v5GzZsiDvuuKPby9puvvnmGDRoUBx77LFb/b7GxsaYMmVK3HrrrfGlL30pWlpaIuL1l/UtWLAgzjvvvP7+yEAdaGDP+ttAoFg0sGc70sDNC48nn3wy5s+fH//jf/yPfv6UQL1pYM9q/TjwmWeeiUcffTTe+9739vl7gfrQv571t3/Tp0+PCRMmbHH8cccdFyeffHL8xV/8RYwZM6YPPyn1YOlRMQcffHBERHz5y1+OadOmxeDBg+OP/uiPuv5YX0v77rtvfPGLX4yLL744nnzyyTjhhBNi9913j6effjr+/d//vWt7uzVHHHFEnHjiifGud70rdt999/jFL34R//RP/xRHHnlk7Lrrrt1+niuuuCImT54cO+20U7zrXe+K9773vfGpT30q/vRP/zQeeuihOPbYY2PIkCGxevXquP/+++Pggw+Os846q+u69thjjzjrrLNixYoVccABB8TcuXPjuuuui7POOiv22Wefbf6cl156aRx++OFx4oknxoUXXhgvvfRS/PVf/3Xsueee8bnPfa4GtyRQKxpY+wb+93//dyxatCgioutVb3fffXfstddesddee8X48eN36HYEakcDa9vAjRs3xqRJk+KRRx6JOXPmxKZNm2LJkiVdp++1116x33777ehNCdSIBta2gevWrYvjjz8+Tj/99Nh///2jubk5fvWrX8WXv/zl6OzsjEsuuaRGtyawo/Svtv3bd999Y9999+3xtLe+9a09LkTIQJafok42LrrootTR0ZEGDRqUIiItWLAgpZTS+PHj0/jx47vOt3z58hQR6corr+z2/QsWLEgRkX7wgx90O/76669PEZEefPDBbsffdttt6bjjjktDhw5NTU1NadSoUenUU09NP/nJT7Y554UXXpgOO+ywtPvuu6empqb0tre9LZ133nnpmWee6TpPZ2dnOuOMM9Jee+2VGhoaUkSk5cuXd53+rW99Kx1xxBFpyJAhqbm5Oe23337pE5/4RHrooYe6zjN+/Ph00EEHpYULF6bDDjssNTU1pREjRqQvfOEL6ZVXXunNTZoeeuih9D//5/9Mu+66axo6dGg6+eST0xNPPNGr7wUGlgbWtoGbb4+eDm+8PYF80MDaNXDzbbS1w7Rp07b5/cDA08DaNfCll15KZ5xxRnrHO96Rdtttt9TY2Jj23nvv9LGPfSwtW7Zsm98LDDz9q/3fAt8sItKMGTP69b3UXkNKKdVxpwK5N2HChHjm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nXfeGRdeeGHcfPPNcfzxx8crr7yS6Wy8rjHrAciPd77znVmPUFiDBg2KcePGZT0GsAM0sH/+4R/+Ie6+++7413/9124d/OM//uMMpwL6SgP7p6fHf1//+tejoaEh/uzP/iyDiYD+0MD++da3vhVHH310XHvttV3HHX/88dHe3h433HBDTJ06NcPpgN7Qv7777W9/G1/+8pdjxowZccUVV0TE6+0bPnx4nH766fHtb387zjzzzIynxCs9KmTmzJnxl3/5lxERMXr06K6X3i9cuDAitnxJ21NPPRUNDQ1x5ZVXxhVXXBH77rtvNDc3x4QJE+JXv/pVvPLKK3HhhRdGR0dHtLa2ximnnBJr167d4npvueWWOPLII2PIkCGx2267xaRJk+KRRx7Z7rwvvvhiXHDBBTF69OjYZZddYtiwYXHYYYfFd7/73Yh4/W2lvvrVr0ZE97cWeOqppyLi9ZeaXXPNNTF27Nhobm6O3XffPU499dR48sknu13PhAkTYsyYMfHTn/40xo0bF83NzfHWt741/uqv/ipeffXVvt7MQE5pYH0a+OUvfzmOPfZYi1/IOQ0cmMeBGzZsiB/84Acxfvz4ePvb397n7wfqQwPr08DBgwdHa2trt+N22WWXrgOQPf2rff+WLFkSr776anzgAx/odvyJJ54YERH//M//vN2fkwGQqIyVK1emc845J0VEuvXWW9MDDzyQHnjggbRu3bqUUkrjx49P48eP7zr/8uXLU0SkUaNGpSlTpqQ777wzfec730ltbW3pgAMOSB//+MfTJz/5yXT33Xenr33ta2m33XZLU6ZM6Xadf/d3f5caGhrSJz/5yXTnnXemW2+9NR155JFpyJAhadmyZduc99Of/nTadddd0+zZs9OCBQvSnXfemS6//PL0D//wDymllJ544ol06qmnpojo+lkeeOCB9NJLL6WUUjrzzDPT4MGD0+c+97l0zz33pJtvvjkdeOCBqa2tLa1Zs6bresaPH5/22GOP1NHRkb7yla+kefPmpT//8z9PEZFmzJix3dt12rRpadCgQamtrS0NGjQovfWtb00zZsxIzz77bK9+L8DA0MDaN3DFihUpItI555yTLrroojR8+PC00047pXe+853p29/+dq9/N0D9aWB9Hge+2Te+8Y0UEek73/lOn78XqB8NrE8D//f//t9pp512Sv/4j/+Yfve736VVq1al8847L+2yyy7p/vvv79XvBqgv/at9/26++eYUEenee+/tdvzGjRtTQ0NDGjFixLZ/KQwIS4+KufLKK1NEpOXLl29x2tZCd8ghh6RXX3216/g5c+akiEgf/OAHu33/ueeemyKiK5wrVqxIjY2N6Zxzzul2vg0bNqT29vb04Q9/eJuzjhkzJp188snbPM+MGTNST7u7Bx54IEVEuuqqq7odv3LlytTc3Jw+//nPd/u5IyLdfvvt3c575plnpkGDBqVf//rX25xh9uzZafbs2enHP/5x+vGPf5wuvvjitOuuu6YDDzwwbdiwYZvfCwwsDaxtAzdfz9ChQ9M73/nO9P3vfz/Nmzev60HoN77xjW3ODwwsDaz948A3O+KII9Jb3vKWtHHjxj59H1B/GlifBn7ta19LTU1NKSJSRKRhw4al+fPnb/f7gIGjf7Xt39KlS1NEpL/5m7/pdvy//Mu/pIhIO++88zbnZ2B4eyu26wMf+EAMGvSHfyrveMc7ImLL92vffPyKFSsiImLevHmxadOm+MQnPhGbNm3qOuyyyy4xfvz4rpfSbc173vOeuPvuu+PCCy+MhQsXxsaNG3s985133hkNDQ3xsY99rNt1t7e3xyGHHLLFdbe0tMQHP/jBbsedfvrp8dprr8V99923zes677zz4rzzzovjjz8+jj/++Pjbv/3buPHGG+OXv/xlXHfddb2eGcgnDdx6A1977bWIiHjppZdi7ty58Sd/8icxceLE+P73vx/vfve744tf/GKvZwbySQO3/TjwjZYtWxb/9m//Fv/rf/0vb+sCJaGB227g9ddfH3/xF38RZ599dvzkJz+JuXPnxsSJE+Okk06KefPm9XpmIH/0b+v9O+SQQ+LYY4+NK6+8Mn7wgx/E888/H4sXL47PfOYzsdNOO3W73ciODzJnu4YNG9bt65133nmbx7/00ksREfH0009HRMThhx/e4+VuLwJf+cpXYu+9945bbrklrrjiithll11i0qRJceWVV8b++++/ze99+umnI6UUbW1tPZ7+tre9rdvXPZ2vvb09IiKeffbZbV5XT0455ZQYMmRILFmypM/fC+SLBm69gXvssUdERBx44IExatSoruMbGhpi0qRJMWvWrFi7dm0MHz58m/MC+aWBvX8c+M1vfjMiIs4444xefw+Qbxq49QY+99xzMWPGjDjjjDPi7//+77uOnzx5ckyYMCE+85nPxPLly7c5K5Bf+rftx4A/+MEPYvr06fHhD384Il6/Hc4777z4yU9+Es8///w2v5eBYelB3ey5554REfHDH/6w2x/DemvIkCFx6aWXxqWXXhpPP/1016Z3ypQp8ctf/nK7193Q0BA//elPo6mpaYvT33zc5ii/0Zo1ayLiD3/U66uUku0uVFgVGrjffvvFrrvu2uNpKaWI2P6DWqCcqtDAN3r55Zfjn/7pn+LQQw+NsWPH9up7gPKqQgMfe+yx2LhxY49/2DzssMNi0aJF8fvf/z522223bc4LlEsV+hcRMXz48Jg7d26sXbs21qxZE6NGjYrm5ua45ppr4tRTT93ej8kAsPSomM138L68PKy/Jk2aFI2NjfFf//Vf8aEPfWiHLqutrS2mT58e//Ef/xFz5syJF198MXbdddduP09zc3PX+U888cS4/PLL47e//W3X1nVbNmzYEHfccUe3l7XdfPPNMWjQoDj22GP7PO8Pf/jDePHFF2PcuHF9/l6gfjSwZ/1tYGNjY5x00knxwx/+MJ566qnYd999I+L1hcc999wT++23X9eDXiB7GtizWjwOvOOOO+KZZ57xtn6QYxrYs/42sKOjIyIilixZEtOmTes6PqUUS5Ysid133z2GDBnS558XqD3961ktHgMOHz68650NvvKVr8QLL7wQZ599dl9+TOrE0qNiDj744IiI+PKXvxzTpk2LwYMHxx/90R9FS0tLza9r3333jS9+8Ytx8cUXx5NPPhknnHBC7L777vH000/Hv//7v3dtb7fmiCOOiBNPPDHe9a53xe677x6/+MUv4p/+6Z/iyCOP7PpfFm/+ea644oqYPHly7LTTTvGud70r3vve98anPvWp+NM//dN46KGH4thjj40hQ4bE6tWr4/7774+DDz44zjrrrK7r2mOPPeKss86KFStWxAEHHBBz586N6667Ls4666zYZ599tjrjr3/96zj99NPjIx/5SLz97W+PhoaGWLRoUcyZMycOOuggb28AOaOBtW1gRMTf/M3fxN133x0nnHBCzJw5M4YOHRr/+I//GP/xH/8R3//+92twSwK1ooG1b+Bm3/zmN6O5uTlOP/30HbjVgHrSwNo2cJ999ompU6fGN77xjWhqaooPfOAD0dnZGTfccEP867/+a/zN3/xNNDQ0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",
      "text/plain": [
       "<Figure size 2000x1000 with 10 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 加载测试集中的单张图片\n",
    "index = 0 # index要处于0-9999之间\n",
    "input, label = test_dataset[index] # 加载数据集时的transform函数已经将数据归一化到[0, 1]范围内\n",
    "input_IMG = torchvision.transforms.ToPILImage()(input)\n",
    "plt.imshow(input_IMG)\n",
    "print(\"原始图像\")\n",
    "print(f\"label: {label}\")\n",
    "plt.show()\n",
    "\n",
    "T = 10 # 把仿真时间T设置为10\n",
    "# 配置编码器\n",
    "encoder = encoding.PoissonEncoder()\n",
    "x_encoded_size = [T, 28, 28] # 编码后的数据大小\n",
    "x_encoded = torch.zeros(x_encoded_size) # 编码后的数据\n",
    "# 开始按照时间逐步编码\n",
    "plt.figure(figsize=(20, 10)) # 设置画图大小\n",
    "print(\"编码后输出图像\")\n",
    "for t in range(T):\n",
    "    x_encoded[t] = encoder(input)\n",
    "    input_IMG = torchvision.transforms.ToPILImage()(x_encoded[t])\n",
    "    plt.subplot(2, 5, t+1)\n",
    "    plt.imshow(input_IMG)\n",
    "    plt.title(f\"time step {t}\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到，在10个时间步长中，原始图像中数值比较高的（比较亮的）部分，比如“7”（index=0）的拐点处，在每一个时间步长中都输出脉冲。\n",
    "\n",
    "而数值比较低的（比较暗的）部分，比如“7”的边缘处，则按照概率在每一个时间步长中输出脉冲。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "SpikingJelly_zzy",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.15"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
